package com.haiwei.poi.word.common;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;

/**
 * 1.临时文件
 * 原因： File.createTempFile 并不会自己delete,违背了从人的角度理解临时文件
 * 临时或者中介文件 应该是用过就自动删除的，如果需要手动删除，那么该方法意义何在呢
 * 原理：
 * 1. HaiweiTempFile 析构方法 finalize 会在该实例在jvm回收的时候调用
 * 2. 临时文件对象回收的时候，顺便删除临时文件对应的文件
 * 3. 临时文件File对象，如果在只有弱引用在引用，则在GC的时候回回收资源
 * 代码：
 * 1. HaiweiTempFile 是File的装饰者，析构的时候回收File资源并删除临时文件
 * 2. HaiweiWeakTempFile 用来创建临时文件，并返回File对象
 * 3.HaiweiWeakTempFile --> HaiweiTempFile
 *   用户File引用 --> HaiweiTempFile.file (如果这个引用断裂,HaiweiTempFile只被弱引用引用就会被收回)
 *
 * @date: 2022-06-23
 * @version: 1.0
 * @author: karry@haiwei.com
 */
public class HaiweiWeakTempFile extends WeakReference<HaiweiWeakTempFile.HaiweiTempFile> {
    
    public static File createTempFile(String prefix, String suffix,File directory)
            throws IOException{
        return new HaiweiWeakTempFile(prefix,suffix,directory).get().getFile();
    }
    
    public static File createTempFile(String prefix, String suffix)
            throws IOException{
        return new HaiweiWeakTempFile(prefix,suffix).get().getFile();
    }
    
    private HaiweiWeakTempFile(String prefix, String suffix) throws IOException {
        super(new HaiweiTempFile(prefix,suffix));
    }
    
    private HaiweiWeakTempFile(String prefix, String suffix, File directory) throws IOException {
        super(new HaiweiTempFile(prefix,suffix,directory));
    }
    
    static class HaiweiTempFile {
        
        private File temp = null;
        
        public HaiweiTempFile(String prefix, String suffix)  throws IOException {
            this.temp = File.createTempFile(prefix,suffix,null);
        }
        
        public HaiweiTempFile(String prefix, String suffix, File directory)  throws IOException {
            super();
            this.temp = File.createTempFile(prefix,suffix,directory);
        }
        
        public File getFile(){
            return this.temp;
        }
        
        @Override
        protected void finalize() throws Throwable {
            if(temp != null && this.temp.exists()){
                this.temp.delete();
            }
        }
        
    }
}
